package xxl.robotlegs.extensions.modularity.impl 
{
	import flash.utils.Dictionary;
	import xxl.robotlegs.extensions.contextsignal.api.IContextSignal;
	import xxl.robotlegs.extensions.contextsignal.impl.ContextSignal;
	import xxl.robotlegs.extensions.modularity.api.IModuleConnectionAction;
	import xxl.robotlegs.extensions.modularity.api.IModuleConnector;
	import xxl.robotlegs.extensions.modularity.ModularityExtension;
	import xxl.robotlegs.framework.api.IContext;
	import xxl.robotlegs.framework.api.IInjector;
	
	/**
	 * ...
	 * @author XXL
	 */
	public class ModuleConnector implements IModuleConnector 
	{
		public static const DEFAULT_CHANNEL_ID:String = "c21f969b5f03d33d43e04f8f136e7682";
		
		private var _configuratorsByChannel:Dictionary = new Dictionary();
		private var _rootInjector:IInjector;
		private var _localContextSignal:IContextSignal;
		
		public function ModuleConnector(context:IContext) 
		{
			const injector:IInjector = context.injector;
			_rootInjector = getRootInjector(injector);
			_localContextSignal = injector.getInstance(IContextSignal);
			context.whenDestroying(destroy);
		}
		
		private function destroy():void 
		{
			for each(var configurator:ModuleConnectionConfigurator in _configuratorsByChannel)
			{
				configurator.destroy();
			}
			_configuratorsByChannel = null;
			_localContextSignal = null;
			_rootInjector = null;
		}
		
		private function getRootInjector(injector:IInjector):IInjector
		{
			while (injector.parent)
			{
				injector = injector.parent;
			}
			return injector;
		}
		
		private function getOrCreateConfigurator(channelId:String):ModuleConnectionConfigurator
		{
			return _configuratorsByChannel[channelId] ||= createConfigurator(channelId);
		}
		
		private function createConfigurator(channelId:String):ModuleConnectionConfigurator
		{
			if (!_rootInjector.hasMapping(IContextSignal, channelId))
			{
				_rootInjector.map(IContextSignal, channelId).toValue(new ContextSignal(String));
			}
			return new ModuleConnectionConfigurator(_localContextSignal, _rootInjector.getInstance(IContextSignal, channelId));
		}
		
		/* INTERFACE xxl.robotlegs.extensions.modularity.api.IModuleConnector */
		
		public function onChannel(channelId:String):IModuleConnectionAction 
		{
			return getOrCreateConfigurator(channelId);
		}
		
		public function onDefaultChannel():IModuleConnectionAction 
		{
			return getOrCreateConfigurator(DEFAULT_CHANNEL_ID);
		}
		
	}

}